package com.dzsw.filter;

import cn.hutool.core.lang.id.NanoId;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Enumeration;

@Slf4j
public class RepeatedReadingRequestFilter implements Filter {

    private String streamPath;

    public RepeatedReadingRequestFilter(String streamPath) {
        this.streamPath = streamPath;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        try {
            RepeatedReadingRequestWrapper requestWrapper = null;
            if (servletRequest instanceof HttpServletRequest) {
                requestWrapper = new RepeatedReadingRequestWrapper((HttpServletRequest) servletRequest);
            }
            if (requestWrapper == null) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                log(requestWrapper);
                filterChain.doFilter(requestWrapper, servletResponse);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (ServletException e) {
            log.error(e.getMessage(), e);
        }
    }

    private void log(RepeatedReadingRequestWrapper requestWrapper) throws IOException {
        String headerSign = "==================== HTTP HEADERS ====================\n";
        String streamFileName = NanoId.randomNanoId();
        String allPath = this.streamPath + streamFileName + ".stream";
        requestWrapper.setAttribute("nanoIdName", streamFileName);
        Path path = Paths.get(allPath);
        if (!Files.exists(path)) {
            Files.createFile(path);
        }
        try (OutputStream writer = Files.newOutputStream(path)) {
            Enumeration<String> enums = requestWrapper.getHeaderNames();
            writer.write(headerSign.getBytes(StandardCharsets.UTF_8));
            for (String name : Collections.list(enums)) {
                writer.write((name + ": " + requestWrapper.getHeader(name) + "\n").getBytes(StandardCharsets.UTF_8));
            }
            writer.write((headerSign + "\n").getBytes(StandardCharsets.UTF_8));
            InputStream inputStream = requestWrapper.getInputStream();
            byte[] buff = new byte[1024];
            int len;
            while((len = inputStream.read(buff)) > 0) {
                writer.write(buff, 0, len);
            }
        }
    }
}
